#include "xcast_handler.h"
#include "channel.h"
#include "listener.h"

template<>
std::set<Channel::Listener::Interface*>
        Base::Listener::Interface<Channel::Listener::Interface>::listener_ =
        std::set<Channel::Listener::Interface*>();

using namespace xcast;

class ChannelListener : public Base::Listener::Interface<Channel::Listener::Interface> {
public:
  static void OnConnected(const char* channelId) {
    for (auto it : listener_) {
      it->OnConnected(channelId);
    }
  }

  static void OnDisconnected(const char* channel_id, int error, const char* err_msg) {
    for (auto it : listener_) {
      it->OnDisconnected(channel_id, error, err_msg);
    }
  }

  static void OnConnecting(const char* channel_id) {
    for (auto it : listener_) {
      it->OnConnecting(channel_id);
    }
  }
};

namespace Channel {
namespace Listener {
void Add(Interface* listener) {
  ChannelListener::Add(listener);
}

void Remove(Interface* listener) {
  ChannelListener::Remove(listener);
}
}  // namespace Listener

namespace XcastEvent {
void OnConnected(const char* channel_id) {
  ChannelListener::OnConnected(channel_id);
}

void OnDisconnected(const char* channel_id, int error, const char* err_msg) {
  ChannelListener::OnDisconnected(channel_id, error, err_msg);
}

void OnConnecting(const char* channel_id) {
  ChannelListener::OnConnecting(channel_id);
}
}

int Join(uint64_t app_id, uint64_t identifier, uint64_t channel_id, const char* auth, uint32_t len) {
#if defined(WIN32)
  xcast_data fmt; fmt["format"] = xc_media_argb32;
  xcast_core::set_property(XC_PREFERENCE_CAMERA, fmt);
  xcast_core::set_property("preference.video.render-format", xcast_data((int32_t)xc_media_argb32)); //for windows render
#endif
  xcast_data params, auth_info, track;

  auth_info["auth_bits"] = -1;
  auth_info.put("auth_buffer", (const uint8_t*)auth, len);
  params["auth_type"] = xc_auth_manual;
  params["auth_info"] = auth_info;

//auto_rotate for mobile program
  xcast_core::set_property("preference.video.auto-rotate", xcast_data(true));
//serve return uint64_t,but actually generate uint32_t，xcast need uint32_t
  params["relation_id"] = (int32_t)channel_id;
  params["role"] = "user";
  params["auto_recv"] = false;
  params["conf_master"] = true;
  params["appid"] = (uint32_t)app_id;
  params["identifier"] = identifier;
  return xcast_core::start_channel("wemeet-channel", params);
}

int Leave() {
  // restructure xcast dont't hava this interface and we also dont't use Leave interface.
//  return xcast_close_channel("wemeet-channel");
  return 1;
}

int SetSpearRole(const char* role) {
  xcast_data params(role);
  return xcast_core::set_property("preference.role", params);
}

const char* GetErrMsg() {
  return xcast_err_msg();
}
}  // namespace Channel
